/** 
Copyright (c) 2010, Sheikh Abdul Wahid Ahmed
Details @ http://extremecodeworld.codeplex.com/license
**/

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using EXtremecode.Common.UI;
using System.Collections;

namespace EXtremecode.PresentationLayer
{
    /// <summary>
    /// Summary description for Decorator
    /// </summary>
    #region Factories

    public class XcodeDecorator : IDecorator
    {

        private static IFrameSubDecorator frameSubDecorator = new XcodeFrameSubDecorator();
        private static IFrameWindowSubDecorator frameWindowSubDecorator = new XcodeFrameWindowSubDecorator();
        private static IButtonSubDecorator buttonSubDecorator = new XcodeButtonSubDecorator();

        public void DecorateFrame(object tbl, string title, string imageURL)
        {
            frameSubDecorator.Decorate(tbl, title, imageURL);
        }

        public void DecorateFrameWindow(object obj, string title, string imageURL)
        {
            frameWindowSubDecorator.Decorate(obj, title, imageURL);
        }

        public void DecorateButton(object obj, string caption, string imageURL)
        {
            buttonSubDecorator.Decorate(obj, caption, imageURL);
        }


    }
    #endregion

    #region Factories sub parts


    public class XcodeFrameSubDecorator : IFrameSubDecorator
    {
        public void Decorate(object obj, string title, string imageURL)
        {
            Table tbl = obj as Table;
            if (tbl == null)
            {
                throw new Exception("Decorated object should be a Table control");
            }
            tbl.CssClass = "XcodeFrameTable";
            tbl.CellPadding = tbl.CellSpacing = 0;
            tbl.BorderWidth = Unit.Pixel(0);

            //GetFirstRow if its type is FrameHeader then remove it.
            //And create new table, insert this row into it 
            //and insert this table into the middle cell of top row
            TableCell barInternalTableContainer = null;
            if (tbl.Rows.Count > 0 && tbl.Rows[0] is FrameHeader)
            {
                //create new table
                Table barTable = new Table();
                barTable.SkinID = "XcodeBarInternalTable";

                //remove first row.
                TableRow tr = tbl.Rows[0];
                tbl.Rows.Remove(tr);

                //add delted row to barTable
                barTable.Rows.Add(tr);

                //add bar table to middle cell.
                barInternalTableContainer = new TableCell();
                barInternalTableContainer.Controls.Add(barTable);
                barInternalTableContainer.SkinID = "XcodeBarInternalTableContainerCell";

            }

            //bar it self a table which contains single row and this row contains
            //four cells. and these cells for
            //LEFT CURVE,TITLE,INTERNAL TABLE and RIGHT CURVE respectively. 

            //create barTable
            Table tblBar = new Table();
            tblBar.SkinID = "XcodeBarTable";
            TableRow rowBar = new TableRow();
            tblBar.Rows.Add(rowBar);

            //create four cell
            TableCell cellLeftCurve = new TableCell();
            TableCell cellTitle = new TableCell();
            TableCell cellInternalTable = (barInternalTableContainer != null) ?
                barInternalTableContainer : new TableCell();
            TableCell cellRightCurve = new TableCell();

            //left curve
            cellLeftCurve.SkinID = "XcodeBarLeftCurve";
            Image imgLeftCurve = new Image();
            imgLeftCurve.SkinID = "XcodeLeftImage";
            cellLeftCurve.Controls.Add(imgLeftCurve);
            rowBar.Cells.Add(cellLeftCurve);

            if (!string.IsNullOrEmpty(imageURL))
            {
                Image headerImage = new Image();
                headerImage.ImageUrl = imageURL;
                TableCell imageCell = new TableCell();
                imageCell.Controls.Add(headerImage);
                rowBar.Cells.Add(imageCell);
                imageCell.SkinID = "XcodeBarIconCell";
            }

            //title
            cellTitle.SkinID = "XcodeBarTitleCell";
            Label lblTitle = new Label();
            lblTitle.Text = title;
            lblTitle.SkinID = "XcodeTitle";
            cellTitle.Controls.Add(lblTitle);
            rowBar.Cells.Add(cellTitle);


            //internal table
            rowBar.Cells.Add(cellInternalTable);


            //Right curve
            cellRightCurve.SkinID = "XcodeBarRightCurve";
            Image imgRightCurve = new Image();
            imgRightCurve.SkinID = "XcodeRightImage";
            cellRightCurve.Controls.Add(imgRightCurve);
            rowBar.Cells.Add(cellRightCurve);

            //now insert new row and add this bar table into it. we need colspan for this row so first calcuate it.

            //Get sum of colspan
            int colspan = 0;
            if (tbl.Rows.Count > 0)
            {
                foreach (TableCell tc in tbl.Rows[0].Cells)
                {
                    colspan += (tc.ColumnSpan == 0) ? 1 : tc.ColumnSpan;
                }
            }

            //create first row [bar table container]
            TableRow firstRow = new TableRow();
            firstRow.Cells.Add(new TableCell());
            firstRow.Cells[0].ColumnSpan = colspan;
            firstRow.Cells[0].Controls.Add(tblBar);
            tbl.Rows.AddAt(0, firstRow);
        }
    }

    public class XcodeFrameWindowSubDecorator : IFrameWindowSubDecorator
    {
        public void Decorate(object obj, string title, string imageURL)
        {
            Table tbl = obj as Table;
            if (tbl == null)
            {
                throw new Exception("Decorated object should be a Table control");
            }
            tbl.CssClass = "XcodeWindowTable";
            tbl.CellPadding = tbl.CellSpacing = 0;
            tbl.BorderWidth = Unit.Pixel(0);


            //GetFirstRow if its type is FrameHeader then remove it.
            //And create new table, insert this row into it 
            //and insert this table into the middle cell of top row
            TableCell barInternalTableContainer = null;
            if (tbl.Rows.Count > 0 && tbl.Rows[0] is WindowHeader)
            {
                //create new table
                Table barTable = new Table();
                barTable.SkinID = "XcodeWindowBarInternalTable";

                //remove first row.
                TableRow tr = tbl.Rows[0];
                tbl.Rows.Remove(tr);

                //add delted row to barTable
                barTable.Rows.Add(tr);

                //add bar table to middle cell.
                barInternalTableContainer = new TableCell();
                barInternalTableContainer.Controls.Add(barTable);
                barInternalTableContainer.SkinID = "XcodeWindowBarInternalTableContainerCell";

            }

            AddSplitters(tbl);
            if (barInternalTableContainer != null
                || !string.IsNullOrEmpty(title))
            {
                AddHeaderRow(tbl, title, imageURL, barInternalTableContainer);
            }
        }
        private void AddHeaderRow(Table tbl, string title, string imageURL, TableCell barInternalTableContainer)
        {



            //bar it self a table which contains single row and this row contains
            //four cells. and these cells for
            //LEFT CURVE,TITLE,INTERNAL TABLE and RIGHT CURVE respectively. 

            //create barTable
            Table tblBar = new Table();
            tblBar.SkinID = "XcodeWindowBarTable";
            TableRow rowBar = new TableRow();
            tblBar.Rows.Add(rowBar);

            //create four cell
            TableCell cellLeftCurve = new TableCell();
            TableCell cellTitle = new TableCell();
            TableCell cellInternalTable = (barInternalTableContainer != null) ?
                barInternalTableContainer : new TableCell();
            TableCell cellRightCurve = new TableCell();

            //left curve
            cellLeftCurve.SkinID = "XcodeWindowBarLeftCurve";
            Image imgLeftCurve = new Image();
            imgLeftCurve.SkinID = "XcodeWindowLeftImage";
            cellLeftCurve.Controls.Add(imgLeftCurve);
            rowBar.Cells.Add(cellLeftCurve);

            if (!string.IsNullOrEmpty(imageURL))
            {
                Image headerImage = new Image();
                headerImage.ImageUrl = imageURL;
                TableCell imageCell = new TableCell();
                imageCell.Controls.Add(headerImage);
                rowBar.Cells.Add(imageCell);
                imageCell.SkinID = "XcodeWindowBarIconCell";
            }

            //title
            cellTitle.SkinID = "XcodeWindowBarTitleCell";
            Label lblTitle = new Label();
            lblTitle.Text =(string.IsNullOrEmpty(title))
                ? "&nbsp"
                : title;
            lblTitle.SkinID = "XcodeWindowTitle";
            cellTitle.Controls.Add(lblTitle);
            rowBar.Cells.Add(cellTitle);


            //internal table
            rowBar.Cells.Add(cellInternalTable);


            //Right curve
            cellRightCurve.SkinID = "XcodeWindowBarRightCurve";
            Image imgRightCurve = new Image();
            imgRightCurve.SkinID = "XcodeWindowRightImage";
            cellRightCurve.Controls.Add(imgRightCurve);
            rowBar.Cells.Add(cellRightCurve);

            //now insert new row and add this bar table into it. we need colspan for this row so first calcuate it.

            //Get sum of colspan
            int colspan = 0;
            if (tbl.Rows.Count > 0)
            {
                foreach (TableCell tc in tbl.Rows[0].Cells)
                {
                    colspan += (tc.ColumnSpan == 0) ? 1 : tc.ColumnSpan;
                }
            }

            //create first row [bar table container]
            TableRow firstRow = new TableRow();
            firstRow.Cells.Add(new TableCell());
            firstRow.Cells[0].ColumnSpan = colspan;
            firstRow.Cells[0].Controls.Add(tblBar);
            tbl.Rows.AddAt(0, firstRow);
        }

        private void AddSplitters(Table tbl)
        {
            //Make array of rows of current table
            ArrayList rows = new ArrayList(); //for visible rows
            ArrayList invisibleRows = new ArrayList(); //for invisible rows
            foreach (TableRow tr in tbl.Rows)
            {
                if (tr.Visible)
                {
                    rows.Add(tr);
                }
                else
                {
                    invisibleRows.Add(tr);
                }
            }

            //Remove invisible rows.
            foreach (TableRow tr in invisibleRows)
            {
                tbl.Rows.Remove(tr);
            }

            //Get sum of colspan
            int colspan = 0;
            if (tbl.Rows.Count > 0)
            {
                foreach (TableCell tc in tbl.Rows[0].Cells)
                {
                    colspan += (tc.ColumnSpan == 0) ? 1 : tc.ColumnSpan;
                }
            }

            //Get sum of rowspan
            int rowspan = 0;
            if (tbl.Rows.Count > 0)
            {
                foreach (TableRow tr in tbl.Rows)
                {
                    if (tr.Cells.Count > 0)
                    {
                        rowspan += (tr.Cells[0].ColumnSpan == 0) ? 1 : tr.Cells[0].ColumnSpan;
                    }
                }
            }


            //add quantity of row splitter to rowsapn.
            rowspan += (rows.Count == 0) ? 0 : rows.Count - 1;  //RowSplitter is a row.

            //Add quantity of cell splitter and cell separator to colspan
            colspan += (rows.Count == 0 || ((TableRow)rows[0]).Cells.Count == 0) ? 0 : ((TableRow)rows[0]).Cells.Count - 1;


            //Add RowSplitter below of each row except of last. 
            for (int i = 0; i < rows.Count - 1; i++)
            {
                TableRow tr = rows[i] as TableRow;
                TableRow rowSplitter = new TableRow();
                rowSplitter.SkinID = "XcodeSplitterRow";

                Image img = new Image();
                img.SkinID = "XcodeHSplitterImage";

                rowSplitter.Cells.Add(new TableCell());
                rowSplitter.Cells[0].Controls.Add(img);
                rowSplitter.Cells[0].ColumnSpan = colspan;
                tbl.Rows.AddAt(tbl.Rows.GetRowIndex(tr) + 1, rowSplitter);

            }


            //Add CellSplitter after each label cell. 
            if (rows.Count > 0)
            {
                //Make array of cell of first row of current table
                ArrayList cells = new ArrayList();
                foreach (TableCell tc in tbl.Rows[0].Cells)
                {
                    cells.Add(tc);
                }

                for (int i = 0; i < cells.Count - 1; i++)
                {
                    TableCell tc = cells[i] as TableCell;

                    //splitter
                    TableCell cellSplitter = new TableCell();
                    cellSplitter.SkinID = "XcodeCellSplitterCell";


                    //seperator
                    TableCell cellSeperator = new TableCell();
                    cellSeperator.SkinID = "XcodeCellSeperatorCell";

                    //image    
                    Image img = new Image();
                    img.SkinID = "XcodeVSplitterImage";
                    cellSplitter.Controls.Add(img);

                    //after each pair of columns, add separator.
                    //means make splitter to seperator.
                    if (i % 2 != 0)
                    {
                        cellSplitter = cellSeperator;
                    }


                    cellSplitter.RowSpan = rowspan;
                    tbl.Rows[0].Cells.AddAt(tbl.Rows[0].Cells.GetCellIndex(tc) + 1, cellSplitter);
                }

                


                //Add Top Space
                TableRow rowTopSpace = new TableRow();
                rowTopSpace.SkinID = "XcodeWindowTopSpaceRow";
                tbl.Rows.AddAt(0, rowTopSpace);

                TableCell cellTopSpace = new TableCell();
                cellTopSpace.SkinID = "XcodeWindowTopSpaceCell";
                cellTopSpace.ColumnSpan = colspan;
                rowTopSpace.Cells.Add(cellTopSpace);


                //Add Left Border Cell
                //cellLeftBorder

                TableCell cellLeftBorderSpace = new TableCell();
                cellLeftBorderSpace.SkinID = "XcodeWindowLeftBorderSpaceCell";
                cellLeftBorderSpace.RowSpan = rowspan + 1; // 1 for top space 
                tbl.Rows[0].Cells.AddAt(0, cellLeftBorderSpace);
                
                TableCell cellLeftBorder = new TableCell();
                cellLeftBorder.SkinID = "XcodeWindowLeftBorderCell";
                cellLeftBorder.RowSpan = rowspan + 1 + 1; //1 for bottom border and 1 for top space                tbl.Rows[0].Cells.AddAt(0, cellLeftBorder);
                tbl.Rows[0].Cells.AddAt(0, cellLeftBorder);


                Image imgLeftBorder = new Image();
                imgLeftBorder.SkinID = "XcodeWindowLeftBorderImage";
                cellLeftBorder.Controls.Add(imgLeftBorder);


                //Add Right Border Cell
                //cellRightBorder

                TableCell cellRightBorderSpace = new TableCell();
                cellRightBorderSpace.SkinID = "XcodeWindowRightBorderSpaceCell";
                cellRightBorderSpace.RowSpan = rowspan + 1; // 1 for top space
                tbl.Rows[0].Cells.Add(cellRightBorderSpace);

                TableCell cellRightBorder = new TableCell();
                cellRightBorder.SkinID = "XcodeWindowRightBorderCell";
                cellRightBorder.RowSpan = rowspan + 1 + 1;  //1 for bottom border and 1 for top space 
                tbl.Rows[0].Cells.Add(cellRightBorder);


                Image imgRightBorder = new Image();
                imgRightBorder.SkinID = "XcodeWindowRightBorderImage";
                cellRightBorder.Controls.Add(imgRightBorder);
                

                
                //Add Bottom Border
                //cellBottotmBorder
                TableRow rowBottomBorder = new TableRow();
                rowBottomBorder.SkinID = "XcodeWindowBottomBorderRow";
                tbl.Rows.Add(rowBottomBorder);

                
                TableCell cellBottomBorder = new TableCell();
                cellBottomBorder.SkinID = "XcodeWindowBottomBorderCell";
                cellBottomBorder.ColumnSpan = colspan + 2; //2 for space columns
                rowBottomBorder.Cells.Add(cellBottomBorder);
                
                Image imgBottomBorder = new Image();
                imgBottomBorder.SkinID = "XcodeWindowBottomBorderImage";
                cellBottomBorder.Controls.Add(imgBottomBorder);




                //Add Top Border
                //cellTopBorder
                TableRow rowTopBorder = new TableRow();
                rowTopBorder.SkinID = "XcodeWindowTopBorderRow";
                tbl.Rows.AddAt(0, rowTopBorder);


                TableCell cellTopBorder = new TableCell();
                cellTopBorder.SkinID = "XcodeWindowTopBorderCell";
                cellTopBorder.ColumnSpan = colspan + 2 + 2; //2 for space columns 2 for side borders
                rowTopBorder.Cells.Add(cellTopBorder);

                Image imgTopBorder = new Image();
                imgTopBorder.SkinID = "XcodeWindowTopBorderImage";
                cellTopBorder.Controls.Add(imgTopBorder);

                




            }

            //Add invisible Rows Again
            foreach (TableRow tr in invisibleRows)
            {
                tbl.Rows.Add(tr);
            }

        }


    }

    public class XcodeButtonSubDecorator : IButtonSubDecorator
    {
        public void Decorate(object obj, string caption, string ImageURL)
        {
            Table tbl = obj as Table;
            if (tbl == null)
            {
                throw new Exception("Decorated object should be a Table control");
            }
            tbl.CellPadding = tbl.CellSpacing = 0;
            tbl.BorderWidth = Unit.Pixel(0);

            //clear table
            tbl.Rows.Clear();


            //create row with three cells
            TableRow row = new TableRow();
            tbl.Rows.Add(row);

            TableCell cellLeftCurve = new TableCell();
            TableCell cellCaption = new TableCell();
            TableCell cellRightCurve = new TableCell();

            //left curve
            cellLeftCurve.SkinID = "XcodeButtonLeftCurve";
            Image imgLeftCurve = new Image();
            imgLeftCurve.SkinID = "XcodeButtonLeftImage";
            cellLeftCurve.Controls.Add(imgLeftCurve);
            row.Cells.Add(cellLeftCurve);

            //caption
            cellCaption.SkinID = "XcodeButtonCaptionCell";
            Label lblCaption = new Label();
            lblCaption.Text = caption;
            lblCaption.SkinID = "XcodeButtonCaption";
            cellCaption.Controls.Add(lblCaption);
            row.Cells.Add(cellCaption);



            //Right curve
            cellRightCurve.SkinID = "XcodeButtonRightCurve";
            Image imgRightCurve = new Image();
            imgRightCurve.SkinID = "XcodeButtonRightImage";
            cellRightCurve.Controls.Add(imgRightCurve);
            row.Cells.Add(cellRightCurve);

        }
    }

    #endregion
}